import os
import unittest
import uuid
from time import sleep
import xmlrpc.server as server
from functools import partial

import CSYNAC.Server as S
import CSYNAC.Start as s
import CSYNAC.Lib as l
import CSYNAC.FileTree as t
import CSYNAC.Node as Node
import xmlrpc.client as Client
from CSYNAC.FunBase import FunsBase as FunsBase

from test_env import *


class FileTreeTest(unittest.TestCase):
    def setUp(self) -> None:
        DataDir = os.path.abspath('./Data')
        Android_Data = os.path.abspath(os.path.join(DataDir,"Android"))
        self.assertTrue(os.path.exists(DataDir))
        if not os.path.exists('Experiment'):
            os.mkdir('Experiment')
        self.ExpDir = os.path.abspath('Experiment')
        ClientDir = os.path.join(self.ExpDir,"Client")
        if not os.path.exists(ClientDir):
            os.mkdir(ClientDir)
        ClientDir = os.path.abspath(ClientDir)
        self.assertTrue(os.path.isdir(ClientDir))
        Android_Client = os.path.join(ClientDir,'Android')
        if not os.path.exists(Android_Client):
            os.system("cp -rf \"{}\" \"{}\"".format(DataDir,Android_Client))
        self.assertTrue(os.path.isdir(Android_Client))
        Android_Client = os.path.abspath(Android_Client)

    def tearDown(self) -> None:
        os.system("rm -rf ./Experiment/Client")


    def test_file_tree(self):
        F = t.SFolder("Experiment/Client/Android/")
        F.analyze()
        def f(test:unittest.TestCase,self:t.File):
            if type(self)==t.File:
                test.count_file = test.count_file + 1
            elif type(self)==t.Folder or type(self)==t.SFolder:
                test.count_folder = test.count_folder + 1
            # test.count = test.count+1
            test.assertTrue(os.path.exists(self.apath()))
        self.count_file = 0
        self.count_folder = 0
        F.execute(partial(f,self))
        print(self.count_file)
        print(self.count_folder)


class BaseTestCase(unittest.TestCase):
    Base_bind_ip = 'localhost'
    Base_bind_port = 8000
    Base_listen_ip = '0.0.0.0'
    def setUp(self,):
        # S.close_remote(listen_ip="localhost",port=8000)
        self.server = S.BaseServer(
            hostname=HOSTNAME,
            nodename=Base_Node_Name,listen_ip=Base_listen_ip,port=Base_bind_port,
            bind_ip=Base_bind_ip,back='threading'
        )
        self.server.start("threading")
        sleep(1)

    def tearDown(self, port: int=8000) -> None:
        with Client.ServerProxy(f'http://{Base_bind_ip}:{Base_bind_port}') as client:
            print(client.shutdown() )
        sleep(1)

    def test_echo(self,port=8000):
        query = "Hello World!"
        with Client.ServerProxy("http://{}:{}".format(Base_bind_ip, port)) as client:
            client:FunsBase
            reply = client.echo(query)
        self.assertEqual(query, reply)

    def test_pass(self):
        pass



class LibTestCase(unittest.TestCase):
    pass
# class SimpleTestCase(unittest.TestCase):
#     def test_server(self):
#         s = central.SimpleXMLRPCServer("localhost",8000)
#         def down(_server):
#             def e()
#             _server.shutdown()
#


class BaseServerTestCase(unittest.TestCase):
    _ip = "0.0.0.0"
    _port = 8000
    base_listen_ip = '0.0.0.0'
    base_bind_ip = 'localhost'
    base_bind_port = 8000

    def c(self,ip=base_bind_ip,port=base_bind_port) -> FunsBase:
        return Client.ServerProxy(f'http://{Base_bind_ip}:{Base_bind_port}')

    def setUp(self,ip=_ip,port=_port) -> None:
        print("port:{}".format(port))
        self.server = S.BaseServer(
            hostname=HOSTNAME,
            nodename=Base_Node_Name,listen_ip=Base_listen_ip,port=Base_bind_port,
            bind_ip=Base_bind_ip,back='threading'
        )
        self.server.start(back='threading')
        sleep(0.5)
        if not os.path.exists("Data"):
            raise Exception("ERROR! 未发现Data文件夹!")
        self.DataDir = os.path.abspath("Data")
        if not os.path.exists("Experiment"):
            os.mkdir("Experiment")
        self.ExpDir = os.path.abspath("Experiment")
        os.system("rm -rf {}/*".format(self.ExpDir))
        self.ServerDir = os.path.join(self.ExpDir,'Server')
        os.mkdir(self.ServerDir)
        self.ClientDir = os.path.join(self.ExpDir,'Client')
        os.mkdir(self.ClientDir)
        self.Files = {file:{
            "org":os.path.join(self.DataDir,file),
            "ser":os.path.join(self.ServerDir,file),
            "cli":os.path.join(self.ClientDir,file)
        } for file in os.listdir(self.DataDir)
            if os.path.isfile(os.path.join(self.DataDir,file))}
        self.files = [file for file in self.Files]
        self.files.sort()
        # self.file_org = {file:os.path.join(self.DataDir,file) for file in self.files}
        self.clear = True

    def tearDown(self,ip=_ip,port=_port) -> None:
        print("port:{}".format(port))
        S.close_remote(ip,port)
        sleep(0.5)
        if self.clear:
            os.system("rm -rf {}/*".format(self.ExpDir))

    def test_start_server(self):    # 启动服务器测试
        pass

    def d(self):
        # os.system("rm -rf ./")
        ExpDir = os.path.abspath("Data")
        print(ExpDir)

    def test_echo(self):            # 消息回显测试
        c = self.c()
        c.echo("回显良好")

    def test_file_md5(self):        # 计算文件的md5值
        files = self.files
        file_one = os.path.abspath(os.path.join(self.DataDir,files[0]))
        file_client = os.path.abspath(os.path.join(self.ClientDir,files[0]))
        os.system("cp {} {}".format(file_one,file_client))
        response = self.c().md5(file_client)
        local = l.md5_file(file_client)
        self.assertEqual(response,local)
        print(local)

    def test_folder_md5(self):      # 计算文件夹的md5
        os.system("cp {}/* {}".format(self.DataDir,self.ClientDir))
        response = self.c().md5(self.ClientDir)
        local = l.md5_folder(self.ClientDir)
        self.assertEqual(response,local)

    def test_file_in(self):         # 写入一个小文件
        files = self.files
        file_one = os.path.abspath(os.path.join(self.DataDir, files[0]))
        file_server = os.path.abspath(os.path.join(self.ServerDir, files[0]))
        file_client = os.path.abspath(os.path.join(self.ServerDir, files[0]))
        os.system("cp {} {}".format(file_one, file_client))
        with open(file_client,'rb') as f:
            data = f.read()
        self.c().file_in(file_server,Client.Binary(data))
        with open(file_server,'rb') as f:
            r_data = f.read()
        self.assertEqual(data,r_data)

    def test_file_out(self):        # 导出一个小文件
        files = [file for file in self.Files]
        file_one = os.path.abspath(os.path.join(self.DataDir, files[0]))
        file_server = os.path.abspath(os.path.join(self.ServerDir, files[0]))
        file_client = os.path.abspath(os.path.join(self.ServerDir, files[0]))
        os.system("cp {} {}".format(file_one, file_server))
        r_data = self.c().file_out(file_server).data
        with open(file_server,'rb') as f:
            data = f.read()
        self.assertEqual(r_data,data)

    def test_folder_report(self):   # 给出文件夹的报告
        os.system("cp {}/* {}".format(self.DataDir,self.ServerDir))
        report = self.c().folder_report(self.ServerDir)
        self.assertEqual(report["path"],self.ServerDir)
        folder_md5 = l.md5_folder(self.ServerDir)
        self.assertEqual(folder_md5,report["md5"])
        for file in os.listdir(self.ServerDir):
            absfile = os.path.join(self.ServerDir,file)
            if os.path.isfile(absfile) :
                md5 = l.md5_file(absfile)
                self.assertEqual(md5,report["files"][absfile])
            self.assertTrue(
                absfile in report["files"] or absfile in report["folders"]
            )

        for file in report["files"]:
            self.assertTrue(os.path.exists(file))
            self.assertEqual(os.path.split(file)[0],self.ServerDir)
        for folder in report["folders"]:
            self.assertTrue(os.path.isdir(folder))
            self.assertEqual(os.path.split(folder)[0],self.ServerDir)

    def test_delete(self):          # 删除单个文件
        os.system("cp {} {}".format(
            self.Files[self.files[0]]["org"],
            self.Files[self.files[0]]["ser"]
        ))
        self.assertTrue(os.path.exists(self.Files[self.files[0]]["ser"]))
        ser = self.c()
        ser.delete(self.Files[self.files[0]]["ser"])
        self.assertFalse(os.path.exists(self.Files[self.files[0]]["ser"]))

    def test_deleteMany(self):      # 批量删除文件
        files_ser = []
        for file in self.files:
            os.system("cp {} {}".format(
                self.Files[file]["org"],
                self.Files[file]["ser"]
            ))
            self.assertTrue(self.Files[file]["ser"])
            files_ser.append(self.Files[file]["ser"])
        ser = self.c()
        ser.deletes(files_ser)
        for file in files_ser:
            self.assertFalse(os.path.exists(file))

    def test_log(self):          # 写入日志测试
        message = "test"
        eventID_1 = uuid.uuid1()
        # self.central.m.log_in(message,eventID=eventID_1)
        self.server.funs.add_log(message,eventID=eventID_1)
        result1 = self.server.m.log_all()
        self.assertEqual(len(result1),1)
        self.assertEqual(result1[0].message,message)
        result2 = self.server.m.log_out_by_eventID(eventID_1)
        self.assertEqual(len(result2),1)
        self.assertEqual(result2[0].message,message)
        eventID_2 = uuid.uuid1()
        self.server.funs.add_log(message="group2_message1",eventID=eventID_2)
        self.server.funs.add_log(message="group2_message2",eventID=eventID_2)
        result3 = self.server.funs.fetch_all_log()
        self.assertEqual(len(result3),3)
        self.assertEqual(len(self.server.m.log_out_by_eventID(eventID_1)),1)
        self.assertEqual(len(self.server.m.log_out_by_eventID(eventID_2)),2)
        self.assertEqual(len(self.server.m.log_out_by_node(Base_Node_Name)),3)

    def test_build_file_tree(self): # 测试建立文件树
        nname = self.server.nodename
        Android_Data = os.path.join(self.DataDir,'Android')
        Android_Server = os.path.join(self.ServerDir,'Android')
        self.assertTrue(os.path.exists(Android_Data))
        self.assertFalse(os.path.exists(Android_Server))
        os.system("cp -rf \"{}\" \"{}\"".format(Android_Data,Android_Server))
        server_stub:FunsBase = self.c()
        server_stub.file_tree_build(Android_Server,nname)
        # task_id = None
        # task_id = server_stub.build_tree(nackname=nname,folder=Android_Server,task_id=uuid.uuid1())
        # task_id = server_stub.build_tree(folder=Android_Server,nackname='BaseServer')
        # while not server_stub.file_tree_check(nname):
        while not server_stub.file_tree_check(nname):
            pass
        server_stub.folder_md5s_calculate(nname)
        # server_stub.tree_md5('BaseServer')
        folder_list = server_stub.folder_md5s_fetch(nname)
        self.assertTrue(nname in self.server.m.SynacFolders)
        self.assertTrue(type(self.server.m.SynacFolders[nname])==t.SFolder)
        SFolder:t.SFolder = self.server.m.SynacFolders[nname]
        for folder in folder_list:
            abspath_folder = SFolder.r_to_apath(folder)
            self.assertTrue(os.path.exists(abspath_folder))
            md5_from_server = folder_list[folder]
            md5_from_local = l.md5_folder(abspath_folder)
            self.assertEqual(md5_from_server,md5_from_local)

    def test_node_add(self):
        '''
        一开始:  Base_Node_Name ,   InYoga,   'localhost'
        第二个:  Central_Node_Name, InYaga,   'localhost'
        第三个:  Node_Node_Name,    InYoga,   'localhost'

        '''
        # test_node = Node.Node(nodename='test_node',hostname='localhost',host_ip='localhost',)
        # self.central.m.node_reg(test_node)
        self.server.funs.node_reg(nodename=Central_Node_Name, hostname=HOSTNAME, host_ip=Central_bind_ip, port=Central_bind_port)
        # all_nodes = self.central.m.node_report()
        all_nodes = self.server.funs.node_report()
        self.assertEqual([nodename for nodename in all_nodes],[Base_Node_Name,Central_Node_Name])
        for i in all_nodes:
            print(i,"\t", all_nodes[i])
        self.assertEqual(len(all_nodes),2)
        client:FunsBase = self.c()
        client.node_reg(Node_Node_Name, HOSTNAME, Node_bind_ip,Node_bind_port)
        report = client.node_report()
        self.assertEqual(len(report),3)
        self.assertTrue(not False in [node in [Base_Node_Name,Central_Node_Name,Node_Node_Name] for node in report])
        client.node_delete(Central_Node_Name)
        report = client.node_report()
        self.assertTrue(not False in [node in [Base_Node_Name,Node_Node_Name] for node in report])


class CentralServerTestCase(unittest.TestCase):
    def setUp(self) -> None:
        self.central = S.CentralServer(
            nodename=Central_Node_Name,
            hostname=HOSTNAME,listen_ip=Central_listen_ip,port=Central_bind_port,
            back='threading',bind_ip=Central_bind_ip)
        self.central.start()
        sleep(1)
        # -----------------------------------------------
        if not os.path.exists("Data"):
            raise Exception("ERROR! 未发现Data文件夹!")
        self.DataDir = os.path.abspath("Data")
        # -----------------------------------------------
        if not os.path.exists("Experiment"):
            os.mkdir("Experiment")
        self.ExpDir = os.path.abspath("Experiment")
        # ----------------------------------------------
        os.system("rm -rf {}/*".format(self.ExpDir))
        self.ServerDir = os.path.join(self.ExpDir,'Server')
        os.mkdir(self.ServerDir)
        self.ClientDir = os.path.join(self.ExpDir,'Client')
        os.mkdir(self.ClientDir)
        self.assertTrue(os.path.exists(self.ServerDir))
        self.assertTrue(os.path.exists(self.ClientDir))
        # ---------------------------------------------
        self.Files = {file:{
            "org":os.path.join(self.DataDir,file),
            "ser":os.path.join(self.ServerDir,file),
            "cli":os.path.join(self.ClientDir,file)
        } for file in os.listdir(self.DataDir)
            if os.path.isfile(os.path.join(self.DataDir,file))}
        self.files = [file for file in self.Files]
        self.files.sort()
        # self.file_org = {file:os.path.join(self.DataDir,file) for file in self.files}
        self.clear = True

    def tearDown(self) -> None:
        S.close_remote(Central_bind_ip,Central_bind_port)
        sleep(0.5)
        if self.clear:
            os.system("rm -rf {}/*".format(self.ExpDir))

    def test_start(self):           # 简单的启动和关闭测试
        pass

    def test_registry(self):        # 注册节点测试
        pass

    def test_inquiry(self):         # 查询节点
        pass


class NodeServerTestCase(unittest.TestCase):
    ip = 'localhost'
    port = 8000
    def setUp(self) -> None:
        self.server = S.NodeServer(
            hostname=HOSTNAME,
            nodename=Node_Node_Name,bind_ip=Node_bind_ip,port=Node_bind_port,
            listen_ip=Node_listen_ip, back='threading',
            central_server_ip=Central_bind_ip,central_server_port=Central_bind_port, reg_at_start=False
        )
        self.server.start('threading')
        sleep(0.5)
        if not os.path.exists("Data"):
            raise Exception("Error! 未发现Data文件夹")
        self.DataDir = os.path.abspath("Data")
        if not os.path.exists("Experiment"):
            os.mkdir("Experiment")
        self.ExpDir = os.path.abspath("Experiment")
        os.system("rm -rf {}/*".format(self.ExpDir))
        self.ServerDir = os.path.join(self.ExpDir,'Server')
        os.mkdir(self.ServerDir)
        self.ClientDir = os.path.join(self.ServerDir,'Client')
        os.mkdir(self.ClientDir)
        self.F = {
            file:{
                "org":os.path.join(self.DataDir,file),
                "ser":os.path.join(self.ServerDir,file),
                "cli":os.path.join(self.ClientDir,file),
            } for file in os.listdir(self.DataDir)
                if os.path.isfile(os.path.join(self.DataDir,file))
        }
        self.files = [file for file in self.F]
        self.files.sort()
        self.clear = True

    def tearDown(self) -> None:
        S.close_remote(ip=Node_bind_ip,port=Node_bind_port)
        sleep(0.5)
        print("port")
        if self.clear:
            os.system("rm -rf {}/*".format(self.ExpDir))

    def c(self)->FunsBase:
        return Client.ServerProxy(f"http://{Node_bind_ip}:{Node_bind_port}")

    def test_start(self):           # 启动服务器
        pass

    def test_echo(self):
        print(self.server.funs.echo("123"))

    def test_registry(self):        # 尝试注册节点
        pass

    def test_build_tree(self):
        Android_org = os.path.join(self.DataDir,'Android')
        self.assertTrue(os.path.exists(Android_org))
        Android_ser = os.path.join(self.ServerDir,'Android')
        Android_cli = os.path.join(self.ClientDir,'Android')
        os.system("cp -rf \"{}\" \"{}\"".format(Android_org,Android_ser))
        self.assertTrue(os.path.exists(Android_org))
        self.assertTrue(os.path.exists(Android_ser))
        c = self.c()
        c.file_tree_build(Android_ser,"test")
        print(self.server.m.SynacFolders['test'].flags)
        c.folder_md5s_calculate('test')
        report = c.folder_md5s_fetch('test')
        print(type(report))

class CooperateTestCase(unittest.TestCase):
    def setUp(self) -> None:
        # self.central = S.CentralServer(hostname="CentralServer",nodename='Central',
        #     listen_ip='localhost',port=sport,back='threading')
        # self.node = S.NodeServer(hostname="NodeServer",nodename='Node',
        #     listen_ip='localhost',port=nport,back='threading')
        self.server = S.CentralServer(
            hostname=HOSTNAME,
            nodename=Central_Node_Name,bind_ip=Central_bind_ip,port=Central_bind_port,
            listen_ip=Central_listen_ip, back='threading',
        )
        self.server.start()
        print("启动CentralServer!")
        self.node = S.NodeServer(
            hostname=HOSTNAME,
            nodename=Node_Node_Name,bind_ip=Node_bind_ip,port=Node_bind_port,
            listen_ip=Node_listen_ip,back='threading',
            central_server_ip=Central_bind_ip,central_server_port=Central_bind_port, reg_at_start=True
        )
        self.node.start()
        sleep(0.5)
        self.assertTrue(os.path.exists('Data'))
        # raise Exception("未完待续!!!")
        self.DataDir = os.path.abspath('Data')
        self.assertTrue(os.path.exists(self.DataDir))
        if not os.path.exists('Experiment'):
            os.mkdir('Experiment')
        self.ExpDir = os.path.abspath('Experiment')
        os.system("rm -rf {}/*".format(self.ExpDir))
        print(os.listdir(self.ExpDir))
        self.assertEqual(len(os.listdir('Experiment')),0)
        os.mkdir(os.path.join('Experiment','Server'))
        os.mkdir(os.path.join('Experiment','Client'))
        self.ServerDir = os.path.join('Experiment','Server')
        self.ClientDir = os.path.join('Experiment','Client')
        self.assertTrue(os.path.exists(self.ServerDir))
        self.assertTrue(os.path.exists(self.ClientDir))
        self.Android_org = os.path.join(self.DataDir,'Android')
        self.Android_ser = os.path.join(self.ServerDir,'Android')
        self.Android_cli = os.path.join(self.ClientDir,'Android')
        self.clear = True

    def tearDown(self) -> None:
        S.close_remote(Central_bind_ip,Central_bind_port)
        S.close_remote(Node_bind_ip,Node_bind_port)
        if self.clear:
            os.system("rm -rf \"{}/*\"".format('Experiment'))
        sleep(0.5)

    def c(self):
        ip = 'localhost'
        return Client.ServerProxy("http://{}:{}".format(Central_bind_ip,Central_bind_port))

    def Android_to_Server(self):
        os.system("cp {} {}".format(self.Android_org,self.Android_ser))

    def Android_to_Client(self):
        os.system(("cp {} {}".format(self.Android_org,self.Android_cli)))

    def test_start(self):
        pass

    def test_single_node_life(self):
        '''
        测试服务器和和一个客户端的连接中的行为,
        包括:
            1. 注册节点
            2. 退出时汇报退出
            3. 判断各时期,系统内节点的信息状况是否正确.
            4. 判断各行为是否写入了正确的log
        :return:
        '''
        pass

    def test_single_file_push(self):
        file = "fig1.png"
        file_org = os.path.join(self.DataDir,file)
        file_ser = os.path.join(self.ServerDir,file)
        file_cli = os.path.join(self.ClientDir,file)
        os.system("cp {} {}".format(file_org,file_cli))
        self.assertTrue(os.path.exists(file_org))
        self.assertTrue(os.path.exists(file_cli))
        with open(file_cli,'rb') as f:
            data = f.read()
        self.c().file_in(file_ser,Client.Binary(data))
        self.assertTrue(os.path.exists(file_ser))
        with open(file_ser,'rb') as f:
            data_ser = f.read()
        self.assertEqual(data,data_ser)

    def test_single_file_pull(self):
        file = "fig1.png"
        file_org = os.path.join(self.DataDir, file)
        file_ser = os.path.join(self.ServerDir, file)
        file_cli = os.path.join(self.ClientDir, file)
        os.system("cp {} {}".format(file_org, file_ser))
        data = self.c().file_out(file_ser).data
        with open(file_ser, 'rb') as f:
            true = f.read()
        self.assertEqual(data, true)

    def test_single_folder_push(self):
        def rname(file):
            return os.path.join(self.ServerDir,file)
        def lname(file):
            return os.path.join(self.ClientDir,file)
        def dname(file):
            return os.path.join(self.DataDir,file)
        def sname(file):
            return os.path.split(file)
        def cp(l,r):
            os.system("cp -rf {} {}".format(l,r))
        files = [file for file in os.listdir(self.DataDir)
                 if os.path.isfile(os.path.join(self.DataDir,file))]
        cp(dname(files[0]),rname(files[0]))
        cp(dname(files[0]),lname(files[0]))
        cp(dname(files[0]),rname(files[1]))
        cp(dname(files[1]),lname(files[1]))
        cp(dname(files[2]),lname(files[2]))
        cp(dname(files[3]),rname(files[3]))
        self.node.funs.push_folder(
            LocalDir=self.ClientDir,RemoteDir=self.ServerDir,
            ip=Central_bind_ip,port=Central_bind_port)
        sreport = l.report_folder(self.ServerDir)
        nreport = l.report_folder(self.ClientDir)
        self.assertEqual(sreport['md5'],nreport['md5'])
        # self.assertEqual(l.report_folder(self.ServerDir),l.report_folder(self.ClientDir))


    def test_single_folder_pull(self):
        def rname(file):
            return os.path.join(self.ServerDir,file)
        def lname(file):
            return os.path.join(self.ClientDir,file)
        def dname(file):
            return os.path.join(self.DataDir,file)
        def sname(file):
            return os.path.split(file)
        def cp(l,r):
            os.system("cp -rf {} {}".format(l,r))
        files = [file for file in os.listdir(self.DataDir)
                 if os.path.isfile(os.path.join(self.DataDir,file))]
        cp(dname(files[0]),rname(files[0]))
        cp(dname(files[0]),lname(files[0]))
        cp(dname(files[0]),rname(files[1]))
        cp(dname(files[1]),lname(files[1]))
        cp(dname(files[2]),lname(files[2]))
        cp(dname(files[3]),rname(files[3]))
        self.node.funs.pull_folder(
            LocalDir=self.ClientDir, RemoteDir=self.ServerDir,
            ip=Central_bind_ip, port=Central_bind_port
        )
        sreport = l.report_folder(self.ServerDir)
        nreport = l.report_folder(self.ClientDir)
        self.assertEqual(sreport['md5'],nreport['md5'])
        self.assertEqual(len(sreport["files"]),3)

    def test_deep_folder_push(self,nackname='test',ip="localhost"):
        def rname(file):
            return os.path.join(self.ServerDir,file)
        def lname(file):
            return os.path.join(self.ClientDir,file)
        def dname(file):
            return os.path.join(self.DataDir,file)
        def sname(file):
            return os.path.split(file)
        def cp(l,r):
            os.system("cp -rf {} {}".format(l,r))
        Android_org = os.path.abspath(os.path.join(self.DataDir,'Android'))
        self.assertTrue(os.path.exists(Android_org))
        Android_ser = os.path.abspath(os.path.join(self.ServerDir,'Android'))
        os.mkdir(Android_ser)
        self.assertTrue(os.path.exists(Android_ser))
        Android_cli = os.path.abspath(os.path.join(self.ClientDir,'Android'))
        cp(Android_org,Android_cli)
        self.assertTrue(os.path.exists(Android_cli))
        # ----------------------------------------------------------------------------------
        self.node.funs._push_mult_folder(
            nackname=nackname,LocalDir=Android_cli,RemoteDir=Android_ser,ip=Central_bind_ip,port=Central_bind_port)
        # ----------------------------------------------------------------------------------
        self.node.funs.file_tree_build(Android_ser,'server_android')
        self.node.funs.folder_md5s_calculate('server_android')
        server_report = self.node.funs.folder_md5s_fetch('server_android')
        self.node.funs.file_tree_build(Android_cli,'client_android')
        self.node.funs.folder_md5s_calculate('client_android')
        client_report = self.node.funs.folder_md5s_fetch('client_android')
        sset = set([folder for folder in server_report])
        cset = set([folder for folder in client_report])
        self.assertEqual(sset,cset)
        for folder in sset:
            self.assertEqual(client_report[folder],server_report[folder])
        self.assertTrue(len(sset)>500)

    def test_deep_folder_pull(self,nackname='test',ip='localhost'):
        def rname(file):
            return os.path.join(self.ServerDir,file)
        def lname(file):
            return os.path.join(self.ClientDir,file)
        def dname(file):
            return os.path.join(self.DataDir,file)
        def sname(file):
            return os.path.split(file)
        def cp(l,r):
            os.system("cp -rf {} {}".format(l,r))
        Android_org = os.path.abspath(os.path.join(self.DataDir,'Android'))
        self.assertTrue(os.path.exists(Android_org))
        Android_cli = os.path.abspath(os.path.join(self.ClientDir,'Android'))
        os.mkdir(Android_cli)
        self.assertTrue(os.path.exists(Android_cli))
        Android_ser = os.path.abspath(os.path.join(self.ServerDir,'Android'))
        cp(Android_org,Android_ser)
        self.assertTrue(os.path.exists(Android_ser))
        # ----------------------------------------------------------------------------------
        self.node.funs._pull_mult_folder(
            nackname=nackname,LocalDir=Android_cli,RemoteDir=Android_ser,ip=Central_bind_ip,port=Central_bind_port)
        # ----------------------------------------------------------------------------------
        self.node.funs.file_tree_build(Android_ser,'server_android')
        self.node.funs.folder_md5s_calculate('server_android')
        server_report = self.node.funs.folder_md5s_fetch('server_android')
        self.node.funs.file_tree_build(Android_cli,'client_android')
        self.node.funs.folder_md5s_calculate('client_android')
        client_report = self.node.funs.folder_md5s_fetch('client_android')
        sset = set([folder for folder in server_report])
        cset = set([folder for folder in client_report])
        self.assertEqual(sset,cset)
        for folder in sset:
            self.assertEqual(client_report[folder],server_report[folder])
        print("-----------\ncount:")
        print(len(sset))
        self.assertTrue(len(sset)>500)


class Mult_Communication(unittest.TestCase):
    def start_central(self):
        self.central = S.CentralServer(
            hostname=HOSTNAME,
            nodename=Central_Node_Name,bind_ip=Central_bind_ip,port=Central_bind_port,
            listen_ip=Central_listen_ip, back='threading',
        )
        self.central.start()

    def start_node_1(self):
        self.node_1 = S.NodeServer(
            hostname=HOSTNAME,
            nodename=N1_Node_Name, bind_ip=N1_bind_ip, port=N1_bind_port,
            listen_ip=N1_listen_ip, back='threading',
            central_server_ip=Central_bind_ip, central_server_port=Central_bind_port, reg_at_start=True
        )
        self.node_1.start()

    def start_node_2(self):
        self.node_2 = S.NodeServer(
            hostname=HOSTNAME,
            nodename=N2_Node_Name, bind_ip=N2_bind_ip, port=N2_bind_port,
            listen_ip=N2_listen_ip, back='threading',
            central_server_ip=Central_bind_ip, central_server_port=Central_bind_port, reg_at_start=True
        )
        self.node_2.start()

    def start_node_3(self):
        self.node_3 = S.NodeServer(
            hostname=HOSTNAME,
            nodename=N3_Node_Name, bind_ip=N3_bind_ip, port=N3_bind_port,
            listen_ip=N3_listen_ip, back='threading',
            central_server_ip=Central_bind_ip, central_server_port=Central_bind_port, reg_at_start=True
        )
        self.node_3.start()

    def test_start_registry(self):
        # 启动中央服务器和多个Node,检测其注册情况.
        self.start_central()
        self.assertTrue(set([node for node in self.central.funs.node_report()]) == {Central_Node_Name})
        self.start_node_1()
        self.assertEqual(set([node for node in self.central.funs.node_report()]), {Central_Node_Name,N1_Node_Name})
        self.assertEqual(set([node for node in self.node_1.funs.node_report()]), {Central_Node_Name,N1_Node_Name})
        self.start_node_2()
        self.assertEqual(set([node for node in self.central.funs.node_report()]), {Central_Node_Name,N1_Node_Name,N2_Node_Name})
        self.assertEqual(set([node for node in self.node_1.funs.node_report()]), {Central_Node_Name,N1_Node_Name,N2_Node_Name})
        self.assertEqual(set([node for node in self.node_2.funs.node_report()]), {Central_Node_Name,N1_Node_Name,N2_Node_Name})
        self.start_node_3()
        self.assertEqual(set([node for node in self.central.funs.node_report()]), {Central_Node_Name,N1_Node_Name,N2_Node_Name,N3_Node_Name})
        self.assertEqual(set([node for node in self.node_1.funs.node_report()]), {Central_Node_Name,N1_Node_Name,N2_Node_Name,N3_Node_Name})
        self.assertEqual(set([node for node in self.node_2.funs.node_report()]), {Central_Node_Name,N1_Node_Name,N2_Node_Name,N3_Node_Name})
        self.assertEqual(set([node for node in self.node_3.funs.node_report()]), {Central_Node_Name,N1_Node_Name,N2_Node_Name,N3_Node_Name})

class CommandLineTestCase(unittest.TestCase):
    '''
    本测试的目的是测试使用命令行操作本程序
    '''
    pass


if __name__ == '__main__':
    unittest.main()
